package com.aleyn.router.inject.instance

/**
 * @author: Aleyn
 * @date: 2023/7/27 12:01
 *
 * 单例实例工厂。
 * 负责创建和管理单例（Singleton）实例。确保在整个应用生命周期中，一个定义只创建一个实例。
 *
 * @param T 实例的类型。
 * @property definition 实例的定义信息。
 */
class SingleInstanceFactory<T>(definition: Definition<T>) : InstanceFactory<T>(definition) {

    // 缓存创建的单例实例
    private var value: T? = null

    // 获取已创建的实例，如果实例为 null 则抛出异常
    private fun getValue(): T = value ?: error("Single instance created couldn't return value")

    /**
     * 检查单例是否已经被创建。
     *
     * @return 如果实例已创建则返回 true，否则返回 false。
     */
    override fun isCreated() = value != null

    /**
     * 创建实例。只有在实例尚未创建时，才会调用父类的创建逻辑。
     *
     * @param context 实例创建时所需的上下文数据。
     * @return 创建或已存在的实例。
     */
    override fun create(context: InstanceData): T {
        return if (value == null) {
            super.create(context)
        } else getValue()
    }

    /**
     * 获取单例实例。
     * 使用双重检查锁定（double-checked locking）模式确保线程安全。
     *
     * @param context 实例创建时所需的上下文数据。
     * @return 单例实例。
     */
    override fun get(context: InstanceData): T {
        // 第一次检查，避免不必要的同步开销
        return value ?: synchronized(this) {
            // 第二次检查，确保在同步块内部实例仍未被创建
            if (!isCreated()) {
                value = create(context)
            }
            // 返回已创建的实例
            return@synchronized getValue()
        }
    }
}